#ifndef GLOBALS_H_
#define GLOBALS_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "parser.h"
#include "utils/md5.h"

#define ELEMENTARY	elementType type;		\
					struct Element 	*next;

#define NEW(x) (x*)memset(malloc(sizeof(x)), 0, sizeof(x))
#define CLEAR(x,t)	memset(x, 0, sizeof(t))

#define VAR(x)	((Variable*)x)
#define MET(x)	((Method*)x)

#define EL(x)	((Element*)x)
#define BEL(x)	((BaseElement*)x)
#define EX(x)	((Expression*)x)
#define IFst(x) ((IfStatement*)x)
	
typedef int elementType;

typedef struct Expression {
	ELEMENTARY
	
	char *exType;
	struct Expression 	*left;
	struct Expression 	*right;
	int				operator;
} Expression;

typedef struct CodeBlock {
	ELEMENTARY
	
	struct Element *content;	
} CodeBlock;

typedef struct BaseElement {
	ELEMENTARY
	
	void *content;	
} BaseElement;

typedef struct IfStatement {
	ELEMENTARY
	
	Expression *expression;
	struct Element *true;
	struct Element *false;
} IfStatement;

typedef struct SwitchStatement {
	
} SwitchStatement;

typedef struct Element {
	elementType		type;
	struct Element 	*next;
} Element;



typedef struct Import {
	char *package;
	char *class;
	char *fullname;
	struct Import *next;
} Import;

typedef struct Variable {
	char *type;
	char *name;
	int  isObject;
	struct Variable *next;
} Variable;

typedef struct Method {
	char *type;
	char *name;
	Variable *args;
	char *argshs;
	Variable *vars;
	Element *code;
	struct Method *next;
} Method;

typedef struct Class {
	char *name;
	char *package;
	char *parent;
	char *fullname;
	
	Variable *vars;
	Method  *methods;
	Method  *constructors;
} Class;

typedef struct Program {
	Class *class;
	Import *imports;
} Program;

Program *program;

/***variables***/
char *__filename;
int __line;
int __column;

/***parser.y***/
int yyparse (void);
void yyerror(char *s);

/***scanner.l***/
void count(void);
void comment();
int check_type(void);
int yylex(void);

/***utils.c***/
void error(char *msg);
void warring(char *msg);
void notice(char *msg);

char *strdcat(char *a, char *b);

void dumpElement(Element *el, int depth);
void dumpParseTree(void);

char *md5string(char *str);

char *translateType(char *typeName);

/***treeGenerator.c***/
Import *addImport(char *classpath);
Import *addLastImport(char *cp);
Import *getImport(char *class);
Import *setLastImport(Import *parent, Import *imp);
Variable *addVariable(char *type, char *name);
Variable *setLastVariable(Variable *parent, Variable *var);
char *getType(char *typename);
Variable *getVariable(char *name, Variable *root);
int isSetVariable(char *name, Variable *root);

Method *addMethod(char *type, char *name, Variable *args, void *code);
Method *addConstructor(char *name, Variable *args, void *code);
Method *getMethod(Method *parent, char *name, char *hash);
Method *setLastMethod(Method *parent, Method *met);

BaseElement *addBaseElement(elementType type, void *content);
Element *setLastElement(Element *parent, Element *el);
Expression *addExpression(Expression *left, Expression *right, int operator);

/***codeGenerator.c***/
void generateCode(FILE *stream);

char *hashArguments(Variable *v);
#endif /*GLOBALS_H_*/

